package com.polaris.live.widget

import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.FrameLayout
import com.polaris.live.R
import com.polaris.live.common.ext.autoDp
import com.polaris.live.databinding.WidgetMusicProgressBinding

/**
 * MusicProgressView
 *
 * @author Created by 天晴 on 2024/9/18 17:51
 * @since 1.0.0
 **/
class MusicProgressView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {

    private val mBinding = WidgetMusicProgressBinding.inflate(LayoutInflater.from(context), this)
    private var max = 100
    private var progress = 0
    private var progressOrientation = 0
    private var mWidth = 0
    private var mHeight = 0
    private var progressRatio = 0.0f
    private var margins = 6.autoDp

    private var progressBack: ((progress: Long) -> Unit)? = null

    init {
        if (attrs != null) {
            val a = context.obtainStyledAttributes(
                attrs, R.styleable.MusicProgressView, 0, 0
            )
            max = a.getInt(R.styleable.MusicProgressView_max, 100)
            progress = a.getInt(R.styleable.MusicProgressView_progress, 0)
            progressOrientation = a.getInt(R.styleable.MusicProgressView_progressOrientation, 0)
            a.recycle()
        }
        progressRatio = progress.toFloat() / max

        if (progressOrientation == 0) {
            val lp = mBinding.musicProgressFl.layoutParams as LayoutParams
            lp.width = ViewGroup.LayoutParams.MATCH_PARENT
            lp.height = 12.autoDp
            lp.gravity = Gravity.CENTER_VERTICAL
            mBinding.musicProgressFl.layoutParams = lp

            val lp2 = mBinding.progress.layoutParams as LayoutParams
            lp2.width = ViewGroup.LayoutParams.MATCH_PARENT
            lp2.height = 2.autoDp
            lp2.marginStart = 6.autoDp
            lp2.marginEnd = 6.autoDp
            lp2.gravity = Gravity.CENTER_VERTICAL
            mBinding.progress.layoutParams = lp2
        } else {
            val lp = mBinding.musicProgressFl.layoutParams as LayoutParams
            lp.width = 12.autoDp
            lp.height = ViewGroup.LayoutParams.MATCH_PARENT
            lp.gravity = Gravity.CENTER_HORIZONTAL
            mBinding.musicProgressFl.layoutParams = lp

            val lp2 = mBinding.progress.layoutParams as LayoutParams
            lp2.width = 2.autoDp
            lp2.height = ViewGroup.LayoutParams.MATCH_PARENT
            lp2.topMargin = 6.autoDp
            lp2.bottomMargin = 6.autoDp
            lp2.gravity = Gravity.CENTER_HORIZONTAL
            mBinding.progress.layoutParams = lp2
        }
    }

    fun setMax(max: Int) {
        this.max = max
        progressRatio = progress.toFloat() / max

        if (progressOrientation == 0) {
            val w = mWidth - 2 * margins
            var tx = progressRatio * w
            if (tx > w - 4) {
                tx = (w - 4).toFloat()
            }
            mBinding.progressIndex.x = tx
        } else {
            val h = mHeight - 2 * margins
            var ty = h - progressRatio * h
            mBinding.progressIndex.y = ty
        }
        invalidate()
    }

    fun getMax(): Int {
        return max
    }

    fun setProgress(progress: Int) {
        this.progress = progress
        progressRatio = progress.toFloat() / max
        if (progressOrientation == 0) {
            val w = mWidth - 2 * margins
            var tx = progressRatio * w
            if (tx > w - 4) {
                tx = (w - 4).toFloat()
            }
            mBinding.progressIndex.x = tx
        } else {
            val h = mHeight - 2 * margins
            var ty = h - progressRatio * h
            mBinding.progressIndex.y = ty
        }
        invalidate()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mWidth = width
        mHeight = height
        setProgress(progress)

    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event == null) {
            return super.onTouchEvent(event)
        }
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                parent.requestDisallowInterceptTouchEvent(true)
                handEvent(event)
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                handEvent(event)
                return true
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                parent.requestDisallowInterceptTouchEvent(false)
                return true
            }

            else -> {
                return super.onTouchEvent(event)

            }
        }

    }

    private fun handEvent(event: MotionEvent) {
        if (progressOrientation == 0) {
            var xx = event.x
            val w = mWidth - 2 * margins
            if (xx < 0) {
                xx = 0f
            }
            if (xx > w) {
                xx = w.toFloat()
            }
            progress = (xx / w * max).toInt()
        } else {
            var yy = event.y

            val h = mHeight - 2 * margins
            if (yy < 0) {
                yy = 0f
            }
            if (yy > h) {
                yy = h.toFloat()
            }
            progress = ((h - yy) / h * max).toInt()
        }
        setProgress(progress)

        progressBack?.invoke((progressRatio * max).toLong())

    }

    fun setSeekToProgress(progressBack: (progress: Long) -> Unit) {
        this.progressBack = progressBack
    }
}